home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / 07.04 Apr 91 / HSIM Code / Harmonic Functs.c next >
Encoding:
C/C++ Source or Header  |  1990-04-25  |  18.5 KB  |  791 lines  |  [TEXT/KAHL]

  1. #include <storage.h>
  2. #include <strings.h>
  3. #include <math.h>
  4.  
  5. #include <QuickDraw.h>
  6. #include <MacTypes.h>
  7. #include <FontMgr.h>
  8. #include <WindowMgr.h>
  9. #include <MenuMgr.h>
  10. #include <TextEdit.h>
  11. #include <DialogMgr.h>
  12. #include <EventMgr.h>
  13. #include <DeskMgr.h>
  14. #include <StdfilePkg.h>
  15. #include <FileMgr.h>
  16. #include <ToolboxUtil.h>
  17. #include <ControlMgr.h>
  18.  
  19.  
  20. #include "Harmonic.h"
  21.  
  22. extern    int        errno;        /* required by math lib */
  23. extern    char    gTAB[];
  24. extern    char    gCR[];
  25.  
  26.  
  27. /*
  28.         Created by    :    Byro
  29.             date    :    03/05/90
  30.         modified    :    04/25/90
  31. */
  32.  
  33. CalcHarmonic(Coeff, dampingCoeff, elasticConst, mass, initInterval, 
  34.                 finalInterval, increment, xLbl, yLbl)
  35.                         
  36.     double    Coeff,
  37.             dampingCoeff,
  38.             elasticConst,    /* comment later */
  39.             mass;
  40.     int        initInterval,
  41.             finalInterval,
  42.             increment;
  43.     char    *xLbl,
  44.             *yLbl;
  45.  
  46. /*
  47.         This section of code is the compute engine of the simple harmonic motion 
  48.     simulator application.  It allocates storage, computes the function, and 
  49.     stores the data before returning to calling routine.
  50. */
  51.  
  52. {
  53.     double    alpha,
  54.             amplitude,
  55.             beta,
  56.             *dataPtr,        /* used for dynamic storage of data pts */
  57.             omega,
  58.             *tPtr;            /* used to free data ptr */
  59.     int        i,
  60.             *t1Ptr,
  61.             *timePtr;
  62.     
  63.     alpha = dampingCoeff / (2 * mass);
  64.     omega = sqrt((double) (4 * mass * elasticConst - (dampingCoeff * dampingCoeff))) / (2 * mass);
  65.     beta = dampingCoeff / (2 * mass * omega);
  66.  
  67.     /* allocate n + 1 doubles;SANE f.p. double uses 10 bytes per number */
  68.         
  69.     dataPtr = (double *) malloc((int) (((finalInterval / increment) * 10) + 10));
  70.     
  71.     /* allocate n + 2 ints; SANE ints use 2 bytes each */
  72.     
  73.     timePtr = (int *) malloc((int) (((finalInterval / increment) * 2) + 4));
  74.     
  75.     if ((dataPtr == NIL) || (timePtr == NIL))
  76.     {
  77.         /* display error dialog */
  78.         
  79.         NoteAlert(ENOUGH_ALERT, NIL);
  80.         return;
  81.     }
  82.     
  83.     tPtr = dataPtr;    /* save ptr to alloced space to free correctly */
  84.     t1Ptr = timePtr;
  85.     
  86.     for (i = initInterval; i <= finalInterval; i += increment)
  87.     {
  88.         /* note the values for cos and sin are in radians */
  89.         
  90.         amplitude = (Coeff * exp((double) (-alpha * i))) * (cos(omega * i)
  91.                         + beta * sin(omega * i));
  92.         
  93.         *dataPtr = amplitude;    /* store value */
  94.         *timePtr = i;    /* store time interval */
  95.         dataPtr++; timePtr++;
  96.     }
  97.     *timePtr = MinusOne;    /* end of data delimiter */ 
  98.     
  99.     /* 
  100.         store labels x, y, and data into an ascii file .  Note: floats must be
  101.         converted to ascii before storing into file.
  102.         Also free data ptr space on exit.
  103.     */
  104.     /* restore ptrs */
  105.     
  106.     dataPtr = tPtr;
  107.     timePtr = t1Ptr;
  108.     
  109.     SaveToFile(xLbl, yLbl, dataPtr, timePtr);
  110.     free(tPtr);
  111.     free(t1Ptr);
  112. }
  113.  
  114.  
  115.  
  116.  
  117. SaveToFile(Xlbl, Ylbl, Dptr, Tptr)
  118.     char    *Xlbl,
  119.             *Ylbl;
  120.     double    *Dptr;
  121.     int        *Tptr;
  122.             
  123. /*
  124.         This function converts the data pts to ascii and writes them to a 
  125.     text file along with their associated axis labels.
  126. */
  127.  
  128. {
  129.     double            tmp;
  130.     int                fRefNum;    /* file reference number */
  131.     long            count;        /* buffer length */
  132.     SFReply            reply;
  133.     static    Str255    Fname = "\p";    /* initialize file name */
  134.     static    Point    where = {100, 104};
  135.     Str255            holder;
  136.     
  137.     SFPutFile(where, "\pSave File as:", "\pSim Result File", 0L, &reply);
  138.     if (reply.good)        /* cancel if button not pressed */
  139.     {
  140.         /* delete existing file */
  141.         
  142.         FSDelete(reply.fName, reply.vRefNum);
  143.         
  144.         /* create nu one */
  145.         
  146.         Create(reply.fName, reply.vRefNum, 'HSIM', 'TEXT');
  147.         if (FSOpen(reply.fName, reply.vRefNum, &fRefNum) == noErr)
  148.         {
  149.             /* write axis labels into file */
  150.             
  151.             strcpy(holder, Xlbl);    /* x-axis */
  152.             count = strlen(holder);
  153.             FSWrite(fRefNum, &count, holder);
  154.             count = 1;
  155.             FSWrite(fRefNum, &count, gCR);    /* write nu line */
  156.  
  157.             
  158.             strcpy(holder, Ylbl);    /* y-axis */
  159.             count = strlen(holder);
  160.             FSWrite(fRefNum, &count, holder);
  161.             count = 1;
  162.             FSWrite(fRefNum, &count, gCR);    /* write nu line */
  163.  
  164.             
  165.             while (*Tptr != MinusOne)
  166.             {
  167.                 if (*Dptr > 0)
  168.                 {
  169.                     /* save only + ive numbers */
  170.                     
  171.                     itoa((int) *Tptr, holder);    /* convert time variable */
  172.                     count = strlen(holder);
  173.                     FSWrite(fRefNum, &count, holder);    /* write time string */
  174.                     
  175.                     count = 1;    /* write tab to file */
  176.                     FSWrite(fRefNum, &count, gTAB);
  177.                     
  178.                     tmp = ceil(*Dptr);    /* round up to next highest int */
  179.                     itoa((int) tmp, holder);    /* convert to ascii string */
  180.                     count = strlen(holder);    /* compute buffer length */
  181.                     FSWrite(fRefNum, &count, holder);    /* write out amplitude */
  182.                     
  183.                     count = 1;
  184.                     FSWrite(fRefNum, &count, gCR);    /* write nu line */
  185.                 }
  186.                 Dptr++;
  187.                 Tptr++; 
  188.             }
  189.             
  190.             /* insures that buffer get written to disk */
  191.             
  192.             FlushVol("\p", reply.vRefNum);
  193.             FSClose(fRefNum);
  194.         }
  195.     }
  196. }
  197.  
  198.  
  199.  
  200.  
  201. HandleDialog(settingsPtr)
  202.     SavedSettingsPtr *settingsPtr;
  203.     
  204. /*
  205.         This funct handles the input of parameters via a dialog.
  206. */
  207.  
  208. {
  209.     int            itemHit,
  210.                 dialogDone = FALSE,
  211.                 frictFlag = FALSE, ampFlag = FALSE, elastFlag = FALSE, 
  212.                 startFlag = FALSE, finiFlag = FALSE, xFlag = FALSE, yFlag = FALSE,
  213.                 massFlag = FALSE, inkFlag = FALSE, simNameFlag = FALSE,
  214.                 itemType;
  215.     Rect        itemRect;
  216.     Handle        itemHandle;
  217.     DialogPtr    settingsDialog;
  218.     
  219.     doDialog(&settingsDialog);    /* create dialog and load default setttings */
  220.     
  221.     /* init settingsPtr with default values here */
  222.     
  223.     SaveDefaults(&settingsDialog, settingsPtr);
  224.     SelectWindow(settingsDialog);
  225.     ShowWindow(settingsDialog);        /* the dialog is initially invisible */
  226.     
  227.     
  228.     while (dialogDone == FALSE)
  229.     {
  230.         ModalDialog(NIL, &itemHit);
  231.         switch (itemHit)
  232.         {
  233.             case OK_BUTTON :
  234.                 HideWindow(settingsDialog);
  235.                 DisposDialog(settingsDialog);
  236.                 dialogDone = TRUE;
  237.                 break;
  238.             case CANCEL_BUTTON :
  239.                 HideWindow(settingsDialog);
  240.                 DisposDialog(settingsDialog);
  241.                 dialogDone = TRUE;
  242.                 return(FALSE);
  243.                 break;
  244.             case FRICTION_VALUE :
  245.                 if (frictFlag == FALSE)
  246.                     SelIText(settingsDialog, FRICTION_VALUE, MIN, MAX);
  247.                 /* get edited value */
  248.                 GetDItem(settingsDialog, FRICTION_VALUE, &itemType, &itemHandle,
  249.                             &itemRect);
  250.                 /* put it in ptr to struct  */
  251.                 GetIText(itemHandle, &(**settingsPtr).frict);
  252.                 frictFlag = TRUE;
  253.                 break;
  254.             case AMPLITUDE_VALUE :
  255.                 if (ampFlag == FALSE)
  256.                     SelIText(settingsDialog, AMPLITUDE_VALUE, MIN, MAX);
  257.                 /* get edited value */
  258.                 GetDItem(settingsDialog, AMPLITUDE_VALUE, &itemType, &itemHandle,
  259.                             &itemRect);
  260.                 /* put it in ptr to struct  */
  261.                 GetIText(itemHandle, &(**settingsPtr).amp);
  262.                 ampFlag = TRUE;
  263.                 break;
  264.             case ELASTIC_VALUE :
  265.                 if (elastFlag == FALSE)
  266.                     SelIText(settingsDialog, ELASTIC_VALUE, MIN, MAX);
  267.                 /* get edited value */
  268.                 GetDItem(settingsDialog, ELASTIC_VALUE, &itemType, &itemHandle,
  269.                             &itemRect);
  270.                 /* put it in ptr to struct  */
  271.                 GetIText(itemHandle, &(**settingsPtr).elastic);
  272.                 elastFlag = TRUE;
  273.                 break;
  274.             case START_VALUE :
  275.                 if (startFlag == FALSE)
  276.                     SelIText(settingsDialog, START_VALUE, MIN, MAX);
  277.                 /* get edited value */
  278.                 GetDItem(settingsDialog, START_VALUE, &itemType, &itemHandle,
  279.                             &itemRect);
  280.                 /* put it in ptr to struct  */
  281.                 GetIText(itemHandle, &(**settingsPtr).start);
  282.                 startFlag = TRUE;
  283.                 break;
  284.             case FINI_VALUE :
  285.                 if (finiFlag == FALSE)
  286.                     SelIText(settingsDialog, FINI_VALUE, MIN, MAX);
  287.                 /* get edited value */
  288.                 GetDItem(settingsDialog, FINI_VALUE, &itemType, &itemHandle,
  289.                             &itemRect);
  290.                 /* put it in ptr to struct  */
  291.                 GetIText(itemHandle, &(**settingsPtr).fini);
  292.                 finiFlag = TRUE;
  293.                 break;
  294.             case X_VALUE :
  295.                 if (xFlag == FALSE)
  296.                     SelIText(settingsDialog, X_VALUE, MIN, MAX);
  297.                 /* get edited value */
  298.                 GetDItem(settingsDialog, X_VALUE, &itemType, &itemHandle,
  299.                             &itemRect);
  300.                 /* put it in ptr to struct  */
  301.                 GetIText(itemHandle, &(**settingsPtr).xVal);
  302.                 xFlag = TRUE;
  303.                 break;
  304.             case Y_VALUE :
  305.                 if (yFlag == FALSE)
  306.                     SelIText(settingsDialog, Y_VALUE, MIN, MAX);
  307.                 /* get edited value */
  308.                 GetDItem(settingsDialog, Y_VALUE, &itemType, &itemHandle,
  309.                             &itemRect);
  310.                 /* put it in ptr to struct  */
  311.                 GetIText(itemHandle, &(**settingsPtr).yVal);
  312.                 yFlag = TRUE;
  313.                 break;
  314.             case MASS_VALUE :
  315.                 if (massFlag == FALSE)
  316.                     SelIText(settingsDialog, MASS_VALUE, MIN, MAX);
  317.                 /* get edited value */
  318.                 GetDItem(settingsDialog, MASS_VALUE, &itemType, &itemHandle,
  319.                             &itemRect);
  320.                 /* put it in ptr to struct  */
  321.                 GetIText(itemHandle, &(**settingsPtr).mass);
  322.                 massFlag = TRUE;
  323.                 break;
  324.             case INC_VALUE :
  325.                 if (inkFlag == FALSE)
  326.                     SelIText(settingsDialog, INC_VALUE, MIN, MAX);
  327.                 /* get edited value */
  328.                 GetDItem(settingsDialog, INC_VALUE, &itemType, &itemHandle,
  329.                             &itemRect);
  330.                 /* put it in ptr to struct  */
  331.                 GetIText(itemHandle, &(**settingsPtr).ink);
  332.                 inkFlag = TRUE;
  333.                 break;
  334.             case SIM_NAME_VALUE :
  335.                 if (simNameFlag == FALSE)
  336.                     SelIText(settingsDialog, SIM_NAME_VALUE, MIN, MAX);
  337.                 /* get edited value */
  338.                 GetDItem(settingsDialog, SIM_NAME_VALUE, &itemType, &itemHandle,
  339.                             &itemRect);
  340.                 /* put it in ptr to struct  */
  341.                 GetIText(itemHandle, &(**settingsPtr).simName);
  342.                 simNameFlag = TRUE;
  343.                 break;
  344.         
  345.         }
  346.     }        /* while */
  347.     if (postProcess(settingsPtr) == FALSE)     /* chk struct for invalid chars */
  348.     {
  349.         /* display error dialogs */
  350.         
  351.         Alert(PROCESS_ALERT, NIL);
  352.         return(FALSE);
  353.     }
  354.     
  355.     /* hndl x, y axis differential chk */
  356.     
  357.     if (validateX(settingsPtr) == FALSE)
  358.     {
  359.         NoteAlert(X_ALERT, NIL);
  360.         return(FALSE);
  361.     }
  362.     if (validateY(settingsPtr) == FALSE)
  363.     {
  364.         NoteAlert(Y_ALERT, NIL);
  365.         return(FALSE);
  366.     }
  367.     
  368.     return(TRUE);
  369. }
  370.  
  371.  
  372.  
  373.  
  374. doDialog(SettingsDialog)
  375.     DialogPtr *SettingsDialog;
  376.     
  377. /*
  378.         create dialog and load default strings.
  379. */
  380.  
  381. {
  382.     int                itemType;
  383.     Rect            itemRect;
  384.     Handle            itemHandle;
  385.     StringHandle    DefFrictH,
  386.                     DefAmpH,
  387.                     DefElastH,
  388.                     DefStartH,
  389.                     DefFiniH,
  390.                     DefXH,
  391.                     DefYH,
  392.                     DefMassH,
  393.                     DefIncH,
  394.                     DefSimNameH;
  395.                     
  396.     DefFrictH = GetString(DEF_FRICTION_ID);    /* generate default string hndls */
  397.     DefAmpH = GetString(DEF_AMPLITUDE_ID);
  398.     DefElastH = GetString(DEF_ELASTIC_ID);
  399.     DefStartH = GetString(DEF_START_ID);
  400.     DefFiniH = GetString(DEF_FINI_ID);
  401.     DefXH = GetString(DEF_X_AXIS_ID);
  402.     DefYH = GetString(DEF_Y_AXIS_ID);
  403.     DefMassH = GetString(DEF_MASS_ID);
  404.     DefIncH = GetString(DEF_INC_ID);
  405.     DefSimNameH = GetString(DEF_SIM_ID);
  406.  
  407.     
  408.     *SettingsDialog = GetNewDialog(BASE_RES_ID, NIL, MOVE_TO_FRONT);
  409.     
  410.     if (*SettingsDialog == NIL)
  411.     {
  412.         /* display malloc dialog error */
  413.         
  414.         StopAlert(ENOUGH_ALERT, NIL);
  415.         ExitToShell();
  416.     }
  417.     
  418.     /* load default settings */
  419.  
  420.     GetDItem(*SettingsDialog, FRICTION_VALUE, &itemType, &itemHandle, &itemRect);
  421.     HLock(DefFrictH);
  422.     SetIText(itemHandle, *DefFrictH);
  423.     HUnlock(DefFrictH);
  424.  
  425.     GetDItem(*SettingsDialog, AMPLITUDE_VALUE, &itemType, &itemHandle, &itemRect);
  426.     
  427.     HLock(DefAmpH);
  428.     SetIText(itemHandle, *DefAmpH);
  429.     HUnlock(DefAmpH);
  430.  
  431.     GetDItem(*SettingsDialog, ELASTIC_VALUE, &itemType, &itemHandle, &itemRect);
  432.  
  433.     HLock(DefElastH);
  434.     SetIText(itemHandle, *DefElastH);
  435.     HUnlock(DefElastH);
  436.  
  437.     GetDItem(*SettingsDialog, START_VALUE, &itemType, &itemHandle, &itemRect);
  438.  
  439.     HLock(DefStartH);
  440.     SetIText(itemHandle, *DefStartH);
  441.     HUnlock(DefStartH);
  442.  
  443.     GetDItem(*SettingsDialog, FINI_VALUE, &itemType, &itemHandle, &itemRect);
  444.  
  445.     HLock(DefFiniH);
  446.     SetIText(itemHandle, *DefFiniH);
  447.     HUnlock(DefFiniH);
  448.  
  449.     GetDItem(*SettingsDialog, X_VALUE, &itemType, &itemHandle, &itemRect);
  450.  
  451.     HLock(DefXH);
  452.     SetIText(itemHandle, *DefXH);
  453.     HUnlock(DefXH);
  454.  
  455.     GetDItem(*SettingsDialog, Y_VALUE, &itemType, &itemHandle, &itemRect);
  456.  
  457.     HLock(DefYH);
  458.     SetIText(itemHandle, *DefYH);
  459.     HUnlock(DefYH);
  460.  
  461.     GetDItem(*SettingsDialog, MASS_VALUE, &itemType, &itemHandle, &itemRect);
  462.  
  463.     HLock(DefMassH);
  464.     SetIText(itemHandle, *DefMassH);
  465.     HUnlock(DefMassH);
  466.     
  467.     GetDItem(*SettingsDialog, INC_VALUE, &itemType, &itemHandle, &itemRect);
  468.  
  469.     HLock(DefIncH);
  470.     SetIText(itemHandle, *DefIncH);
  471.     HUnlock(DefIncH);
  472.     
  473.     GetDItem(*SettingsDialog, SIM_NAME_VALUE, &itemType, &itemHandle, &itemRect);
  474.  
  475.     HLock(DefSimNameH);
  476.     SetIText(itemHandle, *DefSimNameH);
  477.     HUnlock(DefSimNameH);
  478. }
  479.  
  480.  
  481.  
  482.  
  483. SaveDefaults(myDialog, settings)
  484.     DialogPtr            *myDialog;
  485.     SavedSettingsPtr    *settings;
  486.     
  487. /* puts default settings in structure */
  488.  
  489. {
  490.     int        itemHit,
  491.             itemType;
  492.     Rect    itemRect;
  493.     Handle    itemHndl;
  494.     
  495.     GetDItem(*myDialog, FRICTION_VALUE, &itemType, &itemHndl, &itemRect);
  496.     GetIText(itemHndl, &(**settings).frict);
  497.     
  498.     GetDItem(*myDialog, AMPLITUDE_VALUE, &itemType, &itemHndl, &itemRect);
  499.     GetIText(itemHndl, &(**settings).amp);
  500.  
  501.     GetDItem(*myDialog, ELASTIC_VALUE, &itemType, &itemHndl, &itemRect);
  502.     GetIText(itemHndl, &(**settings).elastic);
  503.  
  504.     GetDItem(*myDialog, START_VALUE, &itemType, &itemHndl, &itemRect);
  505.     GetIText(itemHndl, &(**settings).start);
  506.  
  507.     GetDItem(*myDialog, FINI_VALUE, &itemType, &itemHndl, &itemRect);
  508.     GetIText(itemHndl, &(**settings).fini);
  509.  
  510.     GetDItem(*myDialog, X_VALUE, &itemType, &itemHndl, &itemRect);
  511.     GetIText(itemHndl, &(**settings).xVal);
  512.  
  513.     GetDItem(*myDialog, Y_VALUE, &itemType, &itemHndl, &itemRect);
  514.     GetIText(itemHndl, &(**settings).yVal);
  515.     
  516.     GetDItem(*myDialog, MASS_VALUE, &itemType, &itemHndl, &itemRect);
  517.     GetIText(itemHndl, &(**settings).mass);
  518.     
  519.     GetDItem(*myDialog, INC_VALUE, &itemType, &itemHndl, &itemRect);
  520.     GetIText(itemHndl, &(**settings).ink);
  521.     
  522.     GetDItem(*myDialog, SIM_NAME_VALUE, &itemType, &itemHndl, &itemRect);
  523.     GetIText(itemHndl, &(**settings).simName);
  524. }
  525.  
  526.  
  527.  
  528.  
  529. postProcess(settings)
  530.     SavedSettingsPtr    *settings;
  531.     
  532. /*
  533.         Post Process parses all fields ret'd by input dialog to check for 
  534.     invalid characters.  It returns a value of true to the calling routine
  535.     if all the fields are correct.
  536. */
  537.  
  538. {
  539.     int        num;
  540.     Ptr        chPtr;
  541.     Str255    Astring;
  542.     
  543.     chPtr = (char *) &(**settings).frict;
  544.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  545.         return(FALSE);
  546.         
  547.     chPtr = (char *) &(**settings).amp;
  548.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  549.         return(FALSE);
  550.  
  551.     chPtr = (char *) &(**settings).elastic;
  552.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  553.         return(FALSE);
  554.  
  555.     chPtr = (char *) &(**settings).start;
  556.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  557.         return(FALSE);
  558.     P2Cstr(chPtr, Astring);
  559.     num = atoi(Astring);    /* chk for -ive condition */
  560.     if (num < 0)
  561.         return(FALSE);
  562.  
  563.     chPtr = (char *) &(**settings).fini;
  564.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  565.         return(FALSE);
  566.     P2Cstr(chPtr, Astring);
  567.     num = atoi(Astring);    /*  -ive || equal to 0 condition */
  568.     if ((num < 0) || (num == 0))
  569.         return(FALSE);
  570.  
  571.     chPtr = (char *) &(**settings).mass;
  572.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  573.         return(FALSE);
  574.     P2Cstr(chPtr, Astring);
  575.     num = atoi(Astring);
  576.     if ((num < 0) || (num == 0))
  577.         return(FALSE);
  578.         
  579.     chPtr = (char *) &(**settings).ink;
  580.     if (chkValid(chPtr) == FALSE)    /* ret false if invalid char detected */
  581.         return(FALSE);
  582.     P2Cstr(chPtr, Astring);
  583.     num = atoi(Astring);
  584.     if ((num < 0) || (num == 0))
  585.         return(FALSE);
  586.  
  587.     return(TRUE);
  588. }
  589.  
  590.  
  591.  
  592.  
  593. chkValid(cPtr)
  594.     char    *cPtr;
  595.     
  596. /* 
  597.         checks pascal strings for non-numeric characters and returns true 
  598.     value if no invalid characters are detected.
  599. */
  600.  
  601. {
  602.     char    ch;
  603.     int        i,
  604.             length = 0,
  605.             minusCount = 0,
  606.             plusCount = 0,
  607.             ptCount = 0;
  608.             
  609.     length = *cPtr;        /* extract length of pascal string */
  610.     
  611.     if (length == 0)
  612.         return(FALSE);        /* zero length string */
  613.     
  614.     for (i = 1; i <= length; i++)
  615.     {
  616.         ch = *(cPtr + i);
  617.         if ((ch >= '0') && (ch <= '9'))
  618.             ;
  619.         else
  620.         {
  621.             switch (ch)
  622.             {
  623.                 case '.' :
  624.                     ptCount++;
  625.                     break;
  626.                 case '+' :
  627.                     plusCount++;
  628.                     break;
  629.                 case '-' :
  630.                     minusCount++;
  631.                     break;
  632.                 default :
  633.                     return(FALSE);
  634.                     break;
  635.             }
  636.         }
  637.         
  638.         /* return false if more than one detected */
  639.         
  640.         if ((ptCount > 1) || (plusCount > 1) || (minusCount > 1))
  641.             return(FALSE);
  642.     }
  643.     return(TRUE);
  644. }
  645.  
  646.  
  647.  
  648.  
  649. PtoC(oldSettings, nuSettings)
  650.     SavedSettingsPtr    oldSettings, nuSettings;
  651.     
  652. /*
  653.         Pascal string to C string transforms the pascal strings in the structure
  654.     oldSettings into C strings and places them into the structure nuSettings.
  655. */
  656.  
  657. {
  658.     P2Cstr((*oldSettings).frict, (*nuSettings).frict);
  659.     P2Cstr((*oldSettings).amp, (*nuSettings).amp);
  660.     P2Cstr((*oldSettings).elastic, (*nuSettings).elastic);
  661.     P2Cstr((*oldSettings).start, (*nuSettings).start);
  662.     P2Cstr((*oldSettings).fini, (*nuSettings).fini);
  663.     P2Cstr((*oldSettings).xVal, (*nuSettings).xVal);
  664.     P2Cstr((*oldSettings).yVal, (*nuSettings).yVal);
  665.     P2Cstr((*oldSettings).mass, (*nuSettings).mass);
  666.     P2Cstr((*oldSettings).ink, (*nuSettings).ink);
  667.     P2Cstr((*oldSettings).simName, (*nuSettings).simName);
  668. }
  669.  
  670.  
  671.  
  672.  
  673. validateX(SettingsPtr)
  674.     SavedSettingsPtr    *SettingsPtr;
  675.     
  676. /*
  677.         Validate X checks to see if the differential of x is divisible by ten.
  678.     If it is the function returns a true; otherwise it returns a value of false.
  679. */
  680.  
  681. {
  682.     double    atof();
  683.     int        delta,
  684.             aNumber;
  685.     Str255    Start,
  686.             Finish;
  687.     
  688.     P2Cstr((**SettingsPtr).fini, Finish);    /* convert strs to C strings */
  689.     P2Cstr((**SettingsPtr).start, Start);
  690.     
  691.     delta = atof(Finish) - atof(Start);
  692.     
  693.     aNumber = delta / 10;
  694.     if(aNumber > 0)
  695.         return(TRUE);
  696.     else
  697.         return(FALSE);
  698. }
  699.  
  700.  
  701.  
  702.  
  703. validateY(SettingsPtr)
  704.     SavedSettingsPtr    *SettingsPtr;
  705.     
  706. /*
  707.         Validate Y checks to see if the differential of y is divisible by eight.
  708.     If it is the function returns a true; otherwise it returns a value of false.
  709. */
  710.  
  711. {    
  712.     double    atof();
  713.     int        aNumber;
  714.     Str255    Amp;
  715.     
  716.     P2Cstr((**SettingsPtr).amp, Amp);    /* convert pascal str to C str */
  717.     
  718.     aNumber = atof(Amp);
  719.     if (aNumber >= 8)
  720.         return(TRUE);
  721.     else
  722.         return(FALSE);
  723. }
  724.  
  725.  
  726.  
  727.  
  728. doStatus(Coeff, Mass, Elast, sName, win)
  729.     double        Coeff,
  730.                 Mass,
  731.                 Elast;
  732.     Str255        *sName;
  733.     WindowPtr    *win;
  734.     
  735. /*
  736.         Do Status is used to either store information about the last 
  737.     simulation, or to display the status of the last simulation recorded.
  738.     The action depends on the contents of the parameters passed to the
  739.     routine.
  740. */
  741.  
  742. {
  743.     int        currentRow = 12, leftMargin = 10, rowOffset = 24;
  744.     Str255    num2str;
  745.     
  746.     static Boolean    beenHereBefore = FALSE;
  747.     static double    b = NIL, bSqr = NIL, fourMK = NIL, k = NIL, m = NIL, omega = NIL;
  748.     static Str255    NameOfLastSim;
  749.     
  750.     if ((Mass == NIL) && (beenHereBefore == TRUE))
  751.     {
  752.         /* update screen only */
  753.         
  754.         TextFont(1);    /* change textfont to application */
  755.         
  756.         EraseRect(&(*win)->portRect);
  757.         MoveTo(leftMargin, currentRow);
  758.         DrawString("\pSimulation Name:    ");
  759.         DrawString(&NameOfLastSim);
  760.         currentRow = currentRow + rowOffset;
  761.         MoveTo(leftMargin, currentRow);
  762.         DrawString("\pAngular Velocity:    ");
  763.         NumToString((long) omega, num2str);
  764.         DrawString(num2str);
  765.         currentRow = currentRow + rowOffset;
  766.         MoveTo(leftMargin, currentRow);
  767.         if (bSqr < fourMK)
  768.             DrawString("\pThe function is underdamped");
  769.         if (bSqr > fourMK)
  770.             DrawString("\pThe function is overdamped");
  771.         if (bSqr == fourMK)
  772.             DrawString("\pThe function is critically damped");
  773.         
  774.         TextFont(NIL);    /* reset font to default */
  775.         return(TRUE);
  776.     }
  777.     
  778.     if (Mass != NIL)
  779.     {
  780.         b = Coeff;    /* save input from current simulation */
  781.         m = Mass;
  782.         k = Elast;
  783.         C2Pstr(sName, NameOfLastSim);
  784.         bSqr = b * b;
  785.         fourMK = 4 * m *k;
  786.         omega = (0.5 * m) * sqrt(fourMK - bSqr);
  787.         beenHereBefore = TRUE;
  788.         return(TRUE);
  789.     }
  790.     return(FALSE);
  791. }